(define-module (helpers))


(use-modules
 ;; SRFI-69 for hash tables
 (srfi srfi-69))


(define-public do-n-times
  (λ (proc n)
    (let loop ([n n] [results '()])
      (cond
       [(> n 0)
        (loop (- n 1) (cons (proc) results))]
       [else results]))))


(define-public count-things
  (λ (things thing->hash-key count-proc init-count)
    (let ([count-table (make-hash-table)])
      (for-each
       (λ (thing)
         (let ([hash-key (thing->hash-key thing)])
           (hash-table-set!
            count-table
            hash-key
            (+ (hash-table-ref count-table hash-key (λ () init-count))
               (count-proc thing)))))
       things)
      count-table)))


(define-public simple-count-things
  (λ (things thing->hash-key)
    (count-things things
                  thing->hash-key
                  (λ (thing) 1)
                  0)))


(define-public hash-table-filter-fold
  (lambda* (tab filter-proc acc-proc proc init #:optional (skip-proc #f))
    (hash-table-fold
     tab
     (λ (key val acc)
       (cond
        [(filter-proc key val)
         (acc-proc acc (proc key val))]
        [skip-proc
         (skip-proc key val)]
        [else
         acc]))
     init)))


(define-public if-val-eqv?-seek-debug!
  (λ (val seek debug-proc)
    (cond
     [(eqv? val seek)
      (debug-proc val)
      val]
     [else
      val])))
